// funcs.h

// Copyright (C) 2010  traxex

// Author: 	traxex <traxex@yahoo.cn>
// Created: 	20 Aug 2010
// Version: 	1.0

#pragma once

#include "../cuda_impl/funcs.h"
namespace traxex{
namespace cuda{

template<typename T> vector<T> hamming( uint n){
    vector<T> v(n);
    hamming_k<<<cusize(n)>>>( v, static_cast<T>(2*PI/n));
    return v;
}

namespace{
#define TRAXEX_VECTOR_OP_FUNC( opname, op)                              \
    template<typename T> vector<T> operator op( vector<T>&a, vector<T> &b){ \
        _ensure( a.N==b.N, "assert size(a)==size(b) failed. a(%d), b(%d)", a.N, b.N); \
        vector<T> v(a.N);                                               \
        _##opname##_k<<<cusize(v.N)>>>( v, a, b);                       \
        return v;                                                       \
    }                                                                   \
    template<typename T> vector<T>& operator CAT(op,=)( vector<T>&a, vector<T> &b){ \
        _ensure( a.N==b.N, "assert size(a)==size(b) failed. a(%d), b(%d)", a.N, b.N); \
        _e##opname##_k<<<cusize(a.N)>>>( a, b);                         \
        return a;                                                       \
    }
}
TRAXEX_VECTOR_OP_FUNC( add, +)
TRAXEX_VECTOR_OP_FUNC( sub, -)
TRAXEX_VECTOR_OP_FUNC( mul, *)
TRAXEX_VECTOR_OP_FUNC( div, /)

namespace{
#define TRAXEX_MATRIX_OP_FUNC( opname, op)                              \
    template<typename T> matrix<T> operator op( matrix<T>&a, matrix<T> &b){ \
        _ensure( a.Y==b.Y || a.X == b.X, "assert size(a)==size(b) failed. a(%d,%d), b(%d,%d)", a.Y, a.X, b.Y, b.X); \
        matrix<T> m(a.N);                                               \
        _##opname##_k<<<cusize(m.Y,m.X)>>>( m, a, b);                   \
        return m;                                                       \
    }                                                                   \
    template<typename T> matrix<T>& operator CAT(op,=)( matrix<T>&a, matrix<T> &b){ \
        _ensure( a.Y==b.Y || a.X == b.X, "assert size(a)==size(b) failed. a(%d,%d), b(%d,%d)", a.Y, a.X, b.Y, b.X); \
        _e##opname##_k<<<cusize(a.Y, a.X)>>>( a, b);                    \
        return a;                                                       \
    }
}
TRAXEX_MATRIX_OP_FUNC( add, +)
TRAXEX_MATRIX_OP_FUNC( sub, -)
TRAXEX_MATRIX_OP_FUNC( mul, *)
TRAXEX_MATRIX_OP_FUNC( div, /)

}
}
